// debug.h

// Copyright (C) 2010  traxex

// Author: 	traxex <traxex@yahoo.cn>
// Created: 	18 Apr 2010
// Version: 	1.0
#pragma once
#include <stdio.h>

#define __func__	__PRETTY_FUNCTION__
//log msgs
#define msg_base( color, msg...)                        \
    ({                                                  \
	printf( "[%s:%d]\t%s\n\e[%sm    ",              \
		__FILE__, __LINE__, __func__,color);    \
	printf( msg);                                   \
	printf( "\e[0m\n");                             \
    })


#ifdef  TDEBUG
#	define debugmsg( msg...)	msg_base( "33", msg)
#else
#	define debugmsg( msg...)
#endif

#define logmsg( msg...)			msg_base( "32", msg)
#define errmsg( msg...)			msg_base( "31", msg)


//ensure & safecall
#define _ensure( val, msg...)                   \
    ({                                          \
	if( !val){                              \
	    errmsg( msg);                       \
	    exit( -1);                          \
	}                                       \
    })

#define _safecall( args...)						\
    ({									\
	typeof(args) err = args;					\
	_ensure( err==0, "%s => %s", errcode(err), #args);              \
    })


//typecheck macro
#define _typecheck( var)						\
    printf( "typeof(%s)=%s\n", #var, typeid(typeof(var)).name())


//view vector & matrix
#define _view( fmt, var)                        \
    ({                                          \
	printf( "%s = ", #var);                 \
	printf( fmt, var);                      \
    })

#define _vview( fmt,var,len)                    \
    ({                                          \
	printf( "%s = {\n", #var);              \
	for( int i = 0; i < len; ++i){          \
	    printf( fmt, (var)[i]);             \
	}                                       \
	printf("\n}\n");                        \
    })

#define _mview( fmt,var,xlen,ylen)              \
    ({                                          \
	printf( "%s = {\n", #var);              \
	for( int x = 0; x < xlen; ++x){         \
	    for( int y = 0; y < ylen; ++y){     \
		printf( fmt, (var)[x][y]);      \
	    }                                   \
	    printf("\n");                       \
	}                                       \
	printf("}\n");                          \
    })


#ifdef __CUDACC__
#	define	__KERNEL_SYNC__	cuda::sync()
#else
#	define	__KERNEL_SYNC__
#endif
//check func uses;
#define _timecheck( func...)                            \
    ({                                                  \
        __KERNEL_SYNC__;                                \
	double t1 = timenow();                          \
	(func);                                         \
        __KERNEL_SYNC__;                                \
	double t2 = timenow();                          \
	logmsg( "cost %6.6f\t\t%s", t2-t1, #func);      \
    })

#define _timeused( func...)                             \
    ({                                                  \
        __KERNEL_SYNC__;                                \
	double t1 = timenow();                          \
	(func);                                         \
        __KERNEL_SYNC__;                                \
	double t2 = timenow();                          \
        t2-t1;                                          \
    })
